/**
 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#ifndef _TRANSFER_H
#define _TRANSFER_H

#include <syslog.h>

#define enclave_log(level, fmt, args...) do { \
            syslog(level, "%s[%d]|: " fmt, __func__, __LINE__, ##args); \
} while (0)

#define log_debug(fmt, args...) enclave_log(LOG_DEBUG, fmt, ##args)
#define log_info(fmt, args...) enclave_log(LOG_INFO, fmt, ##args)
#define log_err(fmt, args...) enclave_log(LOG_ERR, fmt, ##args)
#define log_warn(fmt, args...) enclave_log(LOG_WARNING, fmt, ##args)

typedef gint (*thread_func)(gpointer data);

/**
 * struct thread_func_data - Data structure of thread pool function
 * @func:        Callback function registered by user and execute
                 in the new thread
 * @data:        Parameter of the registerd callback function
 */
struct thread_func_data {
    thread_func func;
    gpointer data;
};

/**
 * struct listen_data - Data structure used for epoll event waiting
 * @epoll_fd:        Handle of epoll event
 * @local_fd:        Handle of the local listening socket
 * @events_q:        Epoll event queue used for handling listen socket
                     triggered from epoll event waiting
 * @remote_addr:      ip of the remote server to be transfered
 * @rp:      point of struct addrinfo, allow ipv4 and ipv6
 */
struct listen_data {
    int epoll_fd;
    int local_fd;
    struct epoll_event *events_q;
    char *remote_addr;
    void *rp;
};

/**
 * struct proxy_data - Data structure used for transfer thread
 * @client_fd:        Handle of client socket
 * @remote_addr:      ip of the remote server to be transfered
 * @rp:      point of struct addrinfo, allow ipv4 and ipv6
 */
struct proxy_data {
    int client_fd;
    char *remote_addr;
    void *rp;
};

/**
 * enum transfer_state - States available of transfer.
 * @TRAN_SUCCESS:    Transfer data success
 * @TRAN_FAIL:    Transfer data fail
 * @TRAN_CLOSE:    Src or dst connection has been closed
 */
enum transfer_state {
    TRAN_SUCCESS        = 0,
    TRAN_FAIL           = 1,
    TRAN_CLOSE          = 2,
    TRAN_COMPLETE       = 3,
};

/**
 * create_server_connect() - Create a connection of the remote server
 * @arg:        Parameter used to create server connection
 *
 * Context: Process context.
 * Return:
 * * Positive on success.
 * * Negative return value on failure.
 */
int create_server_connect(const struct proxy_data *arg);

/**
 * transfer_data() - Transfer data between client and server
 * @src_fd:        Handle of the data source socket
   @dst_fd:        Handle of the data destination socket
 *
 * Context: Process context.
 * Return:
 * * Positive on success.
 * * Negative return value on failure.
 */
int transfer_data(int src_fd, int dst_fd);

#endif
